//package com.dnjn.mes.biz.assist;
//
//import com.dnjn.mes.biz.domain.MesEquipment;
//import com.dnjn.mes.biz.service.IMesEquipmentService;
//import com.serotonin.modbus4j.BatchRead;
//import com.serotonin.modbus4j.BatchResults;
//import com.serotonin.modbus4j.ModbusFactory;
//import com.serotonin.modbus4j.ModbusMaster;
//import com.serotonin.modbus4j.code.DataType;
//import com.serotonin.modbus4j.exception.ErrorResponseException;
//import com.serotonin.modbus4j.exception.ModbusInitException;
//import com.serotonin.modbus4j.exception.ModbusTransportException;
//import com.serotonin.modbus4j.ip.IpParameters;
//import com.serotonin.modbus4j.locator.BaseLocator;
//import com.serotonin.modbus4j.msg.*;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
///**
// * from https://zhuanlan.zhihu.com/p/457888323
// */
//@Slf4j
//@Component
//public class Modbus4jHelper {
//    static ModbusFactory modbusFactory;
//
//    static {
//        if (modbusFactory == null) {
//            modbusFactory = new ModbusFactory();
//        }
//    }
//
//    @Autowired
//    private IMesEquipmentService mesEquipmentService;
//
//    /**
//     * todo
//     */
//    public ModbusMaster getMaster() throws ModbusInitException {
//        MesEquipment equipment = mesEquipmentService.fetchCurrent(); //todo
//        String host = equipment.getModbusIp();
//        Integer port = equipment.getModbusPort();
//        return getMaster(host, port);
//    }
//
//    public ModbusMaster getMaster(String host, int port) throws ModbusInitException {
//        IpParameters params = new IpParameters();
//        params.setHost(host);
//        params.setPort(port);
//        //
//        // modbusFactory.createRtuMaster(wapper); //RTU 协议
//        // modbusFactory.createUdpMaster(params);//UDP 协议
//        // modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
//        ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
//        master.init();
//
//        return master;
//    }
//
//    /**
//     * 读取[01 Coil Status 0x]类型 开关数据
//     *
//     * @param slaveId slaveId
//     * @param offset  位置
//     * @return 读取值
//     * @throws ModbusTransportException 异常
//     * @throws ErrorResponseException   异常
//     * @throws ModbusInitException      异常
//     */
//    public Boolean readCoilStatus(int slaveId, int offset)
//            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//        // 01 Coil Status
//        BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
//        Boolean value = getMaster().getValue(loc);
//        return value;
//    }
//
//    /**
//     * 读取[02 Input Status 1x]类型 开关数据
//     */
//    public Boolean readInputStatus(int slaveId, int offset)
//            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//        // 02 Input Status
//        BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
//        Boolean value = getMaster().getValue(loc);
//        return value;
//    }
//
//    /**
//     * 读取[03 Holding Register类型 2x]模拟量数据
//     *
//     * @param slaveId  slave Id
//     * @param offset   位置
//     * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
//     * @return
//     * @throws ModbusTransportException 异常
//     * @throws ErrorResponseException   异常
//     * @throws ModbusInitException      异常
//     */
//    public Number readHoldingRegister(int slaveId, int offset, int dataType)
//            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//        // 03 Holding Register类型数据读取
//        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
//        Number value = getMaster().getValue(loc);
//        return value;
//    }
//
//    /**
//     * 读取[04 Input Registers 3x]类型 模拟量数据
//     *
//     * @param slaveId  slaveId
//     * @param offset   位置
//     * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
//     * @return 返回结果
//     * @throws ModbusTransportException 异常
//     * @throws ErrorResponseException   异常
//     * @throws ModbusInitException      异常
//     */
//    public Number readInputRegisters(int slaveId, int offset, int dataType)
//            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//        // 04 Input Registers类型数据读取
//        BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
//        Number value = getMaster().getValue(loc);
//        return value;
//    }
//
//    /**
//     * 批量读取使用方法
//     *
//     * @throws ModbusTransportException
//     * @throws ErrorResponseException
//     * @throws ModbusInitException
//     */
//    public void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//
//        BatchRead<Integer> batch = new BatchRead<Integer>();
//
//        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
//        batch.addLocator(1, BaseLocator.inputStatus(1, 0));
//
//        ModbusMaster master = getMaster();
//
//        batch.setContiguousRequests(false);
//        BatchResults<Integer> results = master.send(batch);
//        System.out.println(results.getValue(0));
//        System.out.println(results.getValue(1));
//    }
//
//    /**
//     * 写 [01 Coil Status(0x)]写一个 function ID = 5
//     *
//     * @param slaveId     slave的ID
//     * @param writeOffset 位置
//     * @param writeValue  值
//     * @return 是否写入成功
//     * @throws ModbusTransportException
//     * @throws ModbusInitException
//     */
//    public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
//            throws ModbusTransportException, ModbusInitException {
//        // 获取master
//        ModbusMaster tcpMaster = getMaster();
//        // 创建请求
//        WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
//        // 发送请求并获取响应对象
//        WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
//        if (response.isException()) {
//            return false;
//        } else {
//            return true;
//        }
//    }
//
//    /**
//     * 写[01 Coil Status(0x)] 写多个 function ID = 15
//     *
//     * @param slaveId     slaveId
//     * @param startOffset 开始位置
//     * @param bdata       写入的数据
//     * @return 是否写入成功
//     * @throws ModbusTransportException
//     * @throws ModbusInitException
//     */
//    public boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
//            throws ModbusTransportException, ModbusInitException {
//        // 获取master
//        ModbusMaster tcpMaster = getMaster();
//        // 创建请求
//        WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
//        // 发送请求并获取响应对象
//        WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
//        if (response.isException()) {
//            return false;
//        } else {
//            return true;
//        }
//
//    }
//
//    /***
//     * 写[03 Holding Register(4x)] 写一个 function ID = 6
//     *
//     * @param slaveId
//     * @param writeOffset
//     * @param writeValue
//     * @return
//     * @throws ModbusTransportException
//     * @throws ModbusInitException
//     */
//    public boolean writeRegister(int slaveId, int writeOffset, short writeValue)
//            throws ModbusTransportException, ModbusInitException {
//        // 获取master
//        ModbusMaster tcpMaster = getMaster();
//        // 创建请求对象
//        WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
//        WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
//        if (response.isException()) {
//            log.error(response.getExceptionMessage());
//            return false;
//        } else {
//            return true;
//        }
//
//    }
//
//    /**
//     * 写入[03 Holding Register(4x)]写多个 function ID=16
//     *
//     * @param slaveId     modbus的slaveID
//     * @param startOffset 起始位置偏移量值
//     * @param sdata       写入的数据
//     * @return 返回是否写入成功
//     * @throws ModbusTransportException
//     * @throws ModbusInitException
//     */
//    public boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
//            throws ModbusTransportException, ModbusInitException {
//        // 获取master
//        ModbusMaster tcpMaster = getMaster();
//        // 创建请求对象
//        WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
//        // 发送请求并获取响应对象
//        ModbusResponse response = tcpMaster.send(request);
//        if (response.isException()) {
//            log.error(response.getExceptionMessage());
//            return false;
//        } else {
//            return true;
//        }
//    }
//
//    /**
//     * 写入数字类型的模拟量（如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long）
//     *
//     * @param slaveId
//     * @param offset
//     * @param value    写入值,Number的子类,例如写入Float浮点类型,Double双精度类型,以及整型short,int,long
//     * @param dataType ,com.serotonin.modbus4j.code.DataType
//     * @throws ModbusTransportException
//     * @throws ErrorResponseException
//     * @throws ModbusInitException
//     */
//    public void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)
//            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
//        // 获取master
//        ModbusMaster tcpMaster = getMaster();
//        // 类型
//        BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
//        tcpMaster.setValue(locator, value);
//    }
//
//}
